#pragma once
#ifndef __FIXED_BASE_H_INCLUDED__
#define __FIXED_BASE_H_INCLUDED__

#include <vector>

namespace glf {

template<typename T>
struct iterator {
	T operator->() {
		return p;
	}
	const T operator->() const {
		return p;
	}
	T& operator*() const {
		return *p;
	}
	T p;
};

template<typename T>
struct iterable {
	typedef T				value_type;
	typedef T*				pointer;
	typedef const pointer	const_pointer;
	typedef T&				reference;
	typedef const T&		const_reference;
	typedef size_t			size_type;
	typedef ptrdiff_t		difference_type;

	typedef T*										iterator;
    typedef T const*								const_iterator;
    typedef std::reverse_iterator<iterator>			reverse_iterator;
    typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
};

template<typename T>
struct fixed_base_ctor : public iterable<T> {
	fixed_base_ctor(T* buffer) : 
		mSize(0) {
		//mFirst(buffer), 
		//mLast(buffer) {
	}

	size_t size() const {
		return mSize; //mLast - mFirst;
	}

protected:
	size_t mSize;
	//T* mFirst;
	//T* mLast;

};



template<typename T, size_t N>
struct fixed_container : public fixed_base_ctor<T> {
	typedef typename iterable<T>::iterator iterator;
	typedef typename iterable<T>::const_iterator const_iterator;
	typedef std::reverse_iterator<iterator>			reverse_iterator;
    typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;

	fixed_container() :
		fixed_base_ctor<T>(reinterpret_cast<T*>(mBuffer)),
		mDbgElems(reinterpret_cast<T (*)[N]>(mBuffer)) {
	}

	size_t capacity() const {	
		return N;
	}
	size_t max_size() const {
		return N;
		//if(AllowOverflow) {
		//	return size_t(-1);
		//} else {
		//	return N;
		//}
	}

    //iterators
	iterator begin() { 
		return ptr(0);
	}
    const_iterator begin() const { 
		return ptr(0);
	}
    iterator end() { 
		return ptr(this->mSize);
	}
    const_iterator end() const { 
		return ptr(this->mSize);
	}
	reverse_iterator rbegin() { 
	   return reverse_iterator(end()); 
	}
	const_reverse_iterator rbegin() const {
		return const_reverse_iterator(end());
	}
	reverse_iterator rend() { 
		return reverse_iterator(begin()); 
	}
	const_reverse_iterator rend() const {
		return const_reverse_iterator(begin());
	}

protected:
	T* ptr(size_t idx) {
		return reinterpret_cast<T*>(mBuffer) + idx;
	}
#ifdef NN_PLATFORM_CTR /* 3DS */
	// when compiling for the 3DS, the ARM compiler generates an
	// error for the const_iterator begin() const method if
	// T* ptr(size_t idx) const doesn't exists
	T* ptr(size_t idx) const {
		return reinterpret_cast<T*>(mBuffer) + idx;
	}
#endif
	T* first() {
		return ptr(0);
	}
	T* last() {
		return ptr(fixed_base_ctor<T>::size());
	}

	char mBuffer[sizeof(T) * N];
	T (*mDbgElems)[N];
};

#if 0

template<typename T, size_t N, typename A=game_allocator<T> >
struct fixed_growable_container : public fixed_container<T,N> {
	fixed_growable_container() :
		fixed_container(),
		mNewBuffer(0) {
	}

	size_t max_size() const {
		return size_t(-1);
	}

	T* ptr(size_t idx) {
		if(mNewBuffer) {
			return mNewBuffer + idx;
		} else {
			return fixed_container::ptr(idx);
		}
	}

	T* mNewBuffer;
};
#endif

}

#endif
